package ly.count.ohos.sdk;

import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Locale;

/**
 * network utils
 *
 * @since 2021-01-13
 */
public class UtilsNetworking {
    // http://stackoverflow.com/questions/9655181/convert-from-byte-array-to-hex-string-in-java
    private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
    private static final String ENCODE_UTF_8 = "UTF-8";
    private static final int TWO = 2;
    private static final int FOUR = 4;
    private static final int OXFF = 0xff;
    private static final int OXOF = 0x0f;

    private UtilsNetworking() {
    }

    /**
     * encode by given value
     *
     * @param givenValue
     * @return string
     */
    protected static String urlEncodeString(String givenValue) {
        String result = "";

        try {
            result = java.net.URLEncoder.encode(givenValue, ENCODE_UTF_8);
        } catch (UnsupportedEncodingException ignored) {
            // should never happen because ohos guarantees UTF-8 support
        }

        return result;
    }

    /**
     * decode by give value
     *
     * @param givenValue
     * @return string
     */
    protected static String urlDecodeString(String givenValue) {
        String decodedResult = "";

        try {
            decodedResult = java.net.URLDecoder.decode(givenValue, ENCODE_UTF_8);
        } catch (UnsupportedEncodingException ignored) {
            // should never happen because ohos guarantees UTF-8 support
        }

        return decodedResult;
    }

    /**
     * sha256Hash
     *
     * @param toHash
     * @return String
     */
    protected static String sha256Hash(String toHash) {
        String hash = null;
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] bytes = toHash.getBytes(ENCODE_UTF_8);
            digest.update(bytes, 0, bytes.length);
            bytes = digest.digest();

            // This is ~55x faster than looping and String.formating()
            hash = bytesToHex(bytes);
        } catch (NoSuchAlgorithmException e) {
            Countly.sharedInstance().L.e("Cannot tamper-protect params", e);
        } catch (UnsupportedEncodingException e) {
            Countly.sharedInstance().L.e("Cannot tamper-protect params", e);
        }
        return hash;
    }

    /**
     * Get hexadecimal string representation of (a) byte array
     *
     * @param bytes array of bytes to convert
     * @return hex string of the byte array in lower case
     */
    public static String bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * TWO];
        for (int j = 0; j < bytes.length; j++) {
            int v = bytes[j] & OXFF;
            hexChars[j * TWO] = HEX_ARRAY[v >>> FOUR];
            hexChars[j * TWO + 1] = HEX_ARRAY[v & OXOF];
        }
        return new String(hexChars).toLowerCase(Locale.getDefault());
    }

    /**
     * Utility method for testing validity of (a) URL.
     *
     * @param urlStr 物理链接地址字符串
     * @return boolean类型
     */
    @SuppressWarnings("ConstantConditions")
    static boolean isValidUrl(final String urlStr) {
        boolean isValidUrl = false;
        if (urlStr != null && urlStr.length() > 0) {
            try {
                new URL(urlStr);
                isValidUrl = true;
            } catch (MalformedURLException e) {
                isValidUrl = false;
            }
        }
        return isValidUrl;
    }
}
